package Env;
import java.util.Vector;


public class Graph {
	private Edge[][] graph;
	public final int n;
	public float maxEdge;

	private class Edge {
		private float cost;
		private boolean flooded;


		public Edge(float c,boolean flood){
			cost=c;
			flooded=flood;
		}

		public float getCost(){
			return cost;
		}

		public boolean isFlooded(){
			return flooded;
		}

		public void setIsFlooded(boolean flooded){
			this.flooded = flooded ;
		}

		@Override
		public String toString() {
			return "Edge [cost="+ cost + ", flooded=" + flooded + "]";
		}
	}

	/*
	 * Construct a new Graph of size nxn
	 * pre: n>0
	 * post: Graph has no edges
	 */
	public Graph(int n){
		this.n=n;
		graph = new Edge[n+1][n+1];
		maxEdge=0;
	}

	public Graph(Graph old, Car c) {
		n=old.n;
		graph = new Edge[n+1][n+1];
		for (int i=1;i<=old.n;i++)
			for (int j=1;j<=old.n;j++){
				if (old.graph[i][j]!=null)
					if (old.graph[i][j].isFlooded()){
						if (c.getEff()>0)
							this.addEdge(i, j, old.graph[i][j].cost/(c.getSpeed()*c.getEff()),false);
					}else 
						this.addEdge(i, j, old.graph[i][j].cost/(c.getSpeed()), false);

			}
	}

	private float getMaxEdge() {
		return maxEdge;
	}

	/*
	 * adds new edge to the graph
	 */
	void addEdge(int v1, int v2, float cost, boolean flooded) {
		Edge edge = this.new Edge(cost, flooded);
		graph[v1][v2] = edge;
		graph[v2][v1] = edge;
		if (cost>maxEdge)
			maxEdge=cost;
	}

	/*
	 * removes edge between two vertexes if existed
	 */
	void removeEdge(int v1, int v2) {
		graph[v1][v2] = graph[v2][v1] = null;
	}



	public boolean connected(int v1, int v2) {
		return graph[v1][v2] != null;
	}

	public float getEdgeCost(int v1, int v2) throws Exception {
		if (!connected(v1, v2))
			throw new Exception("There's no edge between "+ v1 + " and "+ v2 + "!");

		return graph[v1][v2].getCost();
	}

	public boolean isEdgeFlooded(int v1, int v2) throws Exception {
		if (!connected(v1, v2))
			throw new Exception("There's no edge between "+ v1 + " and "+ v2 + "!");

		return graph[v1][v2].isFlooded();
	}

	public void setIsEdgeFlooded(int v1, int v2, boolean flooded) throws Exception {
		if (!connected(v1, v2))
			throw new Exception("There's no edge between "+ v1 + " and "+ v2 + "!");
		graph[v1][v2].setIsFlooded(flooded);
	}

	@Override
	public String toString() {
		String result = "Graph: " + n + " vertexes.\n";
		int i,j;
		for (i=1; i<=n; i++){
			for (j=i; j<=n; j++)
				if (graph[i][j]!=null)
					result += "v" + i + "--> v" + j + " " + graph[i][j] + "\n";
		}
		return result + "\n";
	}


	public Vector<Integer> getAllConnected(int v){
		Vector<Integer> ans = new Vector<Integer>();
		for (int i=1;i<=n;i++){
			if (graph[v][i]!=null) ans.add(i);
		}
		return ans;
	}
}
